<template>
	<view :class="['comp-role']">
		<view :class="['role',status]"  @animationend="statusAniEnd">
			<view class="role-name">
				{{monster.nickname}}
			</view>
			
			<view class="progress">
				<view class="hp">
					<comp-progress :size="12" activeColor="var(--color-red)" :percent="monster.hp/max_hp * 100"></comp-progress>
					<view class="info-text">{{monster.hp}} / {{max_hp}}</view>
				</view>
				<view class="rate">
					<comp-progress :size="3" activeColor="#0099cc" :percent="rate"></comp-progress>
				</view>
			</view>
		</view>
		<view class="damageData" v-if="damageData.length > 0">
			<block v-for="(item,index) in damageData">
				<view :class="['text',item.damage_type]" v-if="item.visible" @animationend="wavingBloodEnd(index)">{{item.damage_value}}</view>
			</block>
		</view>
	</view>
</template>

<script>
	import { mapState} from "vuex";
	
	import compProgress from "@/components/comp-progress/comp-progress.vue"
	export default {
		name:"comp-monster",
		components:{
			compProgress
		},
		computed : {
			...mapState(['mod_player','current_map','angry_value']),
			player(){
				return this.mod_player.player
			}
		},
		props : ['monster'],
		data() {
			return {
				rate : 0,
				max_hp : 0,
				damageData:[],
				status : 'idle'
			};
		},
		created() {
			
			this.angry_value_max = Object.freeze(getApp().globalData['GAME_DATA']['map'].find(item => item.name == this.player.current_map).angry_value);
		
			this.max_hp = Object.freeze(this.monster.hp);
			this.rate = 0;
			this.status = 'idle'
			
			if(this.worker_setInterval){
				this.worker_setInterval.terminate()
			}

			
			this.worker_setInterval = new Worker('./static/worker/worker_setInterval.js');
			this.worker_setInterval.postMessage({
				interval : 10
			})
			
			this.worker_setInterval.onmessage = (e) => {
				
				if(getApp().globalData['battleEnd']) return;
				
				this.rate += this.monster.spd / 100;
				
				if(this.rate >= 100){
					this.rate = 0;
					this.attack()
				}
			
			}
			
			this.boundUnderAttack = this.underAttack.bind(this);
			uni.$on('player_attack', this.boundUnderAttack)
			
			
		},
		destroyed() {
			this.worker_setInterval.terminate();
			uni.$off('player_attack', this.boundUnderAttack)
		},
		methods : {
			attack(){
				this.status = 'attack'
				
				let monster_damage = this.$common.rnd(this.monster.min_ac,this.monster.max_ac);
				
				let damage_value = Math.max(1,Math.max(1,Math.ceil(monster_damage * monster_damage / (monster_damage + this.$common.rnd(this.player.attr.min_def,this.player.attr.max_def)))) - this.player.attr.fix_def);
				
				uni.$emit('monster_attack',{
					damage_type : 'normal',
					damage_value
				})
			},
			underAttack(attack){
				this.status = 'underAttack'
				
				if(getApp().globalData.appVisibleState == 'onShow'){
					attack.visible = true;
					this.damageData.push(attack)
				}
				this.monster.hp -= attack.damage_value;
				
				if(this.monster.hp <= 0){
					this.dead()
				}
							
				
			},
			dead(){
				
				uni.$off('player_attack', this.boundUnderAttack)

				this.status = 'dead';
				this.monster.hp = 0;
				this.rate=0;
				this.worker_setInterval.terminate();
				
				
				/*
					获得经验 
				*/
				let monster_exp = this.$formula.monster_exp(this.monster.lv);
				let exp_percent =  parseInt(monster_exp * (this.player.attr.exp_percent / 100));
	
				monster_exp += exp_percent
				
				this.$store.commit('mod_player/update_player_resource',{
					type : 'exp',
					value : monster_exp
				})
				

				/* 
					掉落物品 
				*/
				let goods = [];
				let drops = this.monster.drop.split(',');
				let attr = []
				for(let i=0;i<drops.length;i++){
					let item_name = drops[i].split('/')[0];
					let item_drop = drops[i].split('/')[1];
					if(Math.random() <= 1/item_drop){

						if(!getApp().globalData['GAME_DATA']['items'].find(item => item.name == item_name)){
							console.warn(`未配置[${item_name}]数据库，本次掉落无效`);
							continue
						}
						
						
						//装备属性制作
						let equipDataVolume = this.$common.deep_copy(getApp().globalData['GAME_DATA']['items'].find(item => item.name == item_name));
						equipDataVolume.uid = this.$common.create_uid();
						equipDataVolume.qlty = this.$common.probability(getApp().globalData['GAME_DATA']['config'].equip_qlty).qlty;
						
						//装备耐久度，用于重铸
						if(equipDataVolume.qlty > 1){
							equipDataVolume.recast_count = parseInt(equipDataVolume.qlty) + 1;
							equipDataVolume.max_recast_count = parseInt(equipDataVolume.qlty) + 1;
						}else{
							equipDataVolume.recast_count = 0;
							equipDataVolume.max_recast_count = 0;
						}
						

						//装备词条 1白色 //2蓝色 3//黄色 4//红色
						let attr_count = 0;
						
						if(equipDataVolume.qlty == 1){
							attr_count = 0;
						}else if(equipDataVolume.qlty == 2){
							attr_count = 1;
						}else if(equipDataVolume.qlty == 3){
							attr_count = 3;
						}else if(equipDataVolume.qlty == 4){
							attr_count = 4
						}
						
						let rnd_attr = this.$common.getRandomElements(['spd','suck_blood','coin_percent','fix_ac','fix_def','crit','crit_percent','exp_percent'],attr_count);
						rnd_attr.map(attr => {
							equipDataVolume[attr] += this.$common.rnd(1,parseInt(equipDataVolume.qlty)+parseInt(equipDataVolume.lv))
						})
						
						this.$store.commit('mod_player/commit_backpack_add',equipDataVolume);
						

						goods.push({
							name : item_name,
							qlty : equipDataVolume.qlty
						})
						
						
						if(parseInt(equipDataVolume.qlty) >= 4){
							this.$common.send_message(`<span style="color:var(--color-yellow)">[传闻]</span> <span style="color:var(--color-green)">${this.player.nickname}</span> 在 <span style="color:var(--color-green)">${this.player.current_map}</span> 击杀 <span style="color:var(--color-red2)">${this.monster.nickname}</span> 获得了 <span style="color:var(--qlty-${equipDataVolume.qlty})">${item_name}</span>`)
						}
						
						
						
					}
				}
				
				let goods_text = '';
				
				if(goods.length > 0){
					goods.map(item => {
						goods_text += `<span style="color:var(--qlty-${item.qlty})">${item.name}</span> `
					})
				}
				
				/* 
					掉落金币 
					小怪 30%几率 boss 100% 
				*/
				let coin_quantity=0;
				if(this.monster.type == 'monster'){
					if(Math.random() <= 0.3){
						coin_quantity = this.$formula.coin_quantity(this.monster.lv)
					}
				}else{
					coin_quantity = this.$formula.coin_quantity(this.monster.lv)
				}
				
				if(coin_quantity > 0){
					let coin_percent = Math.round(coin_quantity * this.player.attr.coin_percent/100)
					coin_quantity += coin_percent
					goods_text += `金币 <span style="color:var(--color-yellow)">${coin_quantity}</span><span style="font-size:12px;">${coin_percent > 0 ? `(+${coin_percent})` : ''}</span> `
					this.$store.commit('mod_player/update_player_resource',{
						type : 'coin',
						value : coin_quantity
					})
				}
				
				/* 
					boss掉落金刚石
				 */
				if(this.monster.type == 'boss'){
					if(Math.random() <= 0.5){
						let diamond_stone = this.$common.rnd(1,2)
						this.$store.commit('mod_player/update_player_resource',{
							type : 'diamond_stone',
							value : diamond_stone
						})
						goods_text += `金刚石 <span style="color:var(--color-yellow)">${diamond_stone}</span> `
					}
				}

				
				/* 
					播报战报
				 */

				uni.$emit('game-info',{
					content : `<span style="color:var(--color-green)">[战报]</span> 击杀 <span style="color:var(--color-red2)">${this.monster.nickname}[Lv.${this.monster.lv}]</span> 获得 经验 <span style="color:var(--color-green)">${monster_exp}</span><span style="font-size:12px;">${exp_percent > 0 ? `(+${exp_percent})` : ''}</span> ${goods_text ? '获得 ' + goods_text : ''}`
				})
				
				
				/* 
					自动回收 
				*/
				let packItems = this.$common.deep_copy(this.player.backpack);
				packItems.map(equipDataVolume => {
					
					if(!this.player.retrieveValue.qlty) return;
					
					if(this.player.retrieveValue.qlty.includes(parseInt(equipDataVolume.qlty))){
						
						this.$store.commit('mod_player/commit_retrieve_equip',equipDataVolume);

					}

				})
				
				
				/* 
					Boss 愤怒值计算
				 */
				getApp().globalData['battleEnd'] = true;

				if(++getApp().globalData['angry_value'] < this.angry_value_max){
					this.$store.commit('commit_angry_value',getApp().globalData['angry_value'])
					uni.$emit('refreshBattle',{
						type : 'monster'
					});
				}else{
					this.$store.commit('commit_angry_value',getApp().globalData['angry_value'])
					getApp().globalData['angry_value'] = -1
					uni.$emit('refreshBattle',{
						type : 'boss'
					});
				}
				
				
				
				//战斗结束进行内存监测，如果超过限制进行页面刷新释放内存
				if(window.performance.memory.totalJSHeapSize/1024/1024 >= 300){
					this.$common.save_game().then(()=>{
						window.location.reload() 
					})
				}
				
			
			},
			statusAniEnd(){
				if(this.status == 'dead') return;
				this.status = 'idle'
			},
			wavingBloodEnd(index){
				this.damageData[index].visible = false;
			}
		}
	}
</script>

<style lang="scss">
	@include role('monster');
</style>